import { Dimensions, Easing, Animated } from 'react-native';
import { ModalOptions, ModalStackConfig, createModalStack } from 'react-native-modalfy';

import TopicExitModal, { TopicExitModalProps } from './TopicExitModal';

export interface ModalStackParamsList {
  TopicExitModal: TopicExitModalProps;
}

export type ModalName = Extract<keyof ModalStackParamsList, string>;

const { height, width } = Dimensions.get('window');

const config: ModalStackConfig = {
  TopicExitModal: {
    modal: TopicExitModal,
    position: 'center',
    animateInConfig: {
      easing: Easing.inOut(Easing.exp),
      duration: 300,
    },
    animateOutConfig: {
      easing: Easing.inOut(Easing.exp),
      duration: 500,
    },
    transitionOptions: (animatedValue) => ({
      transform: [
        {
          translateY: animatedValue.interpolate({
            inputRange: [0, 1, 2],
            outputRange: [height, 0, height],
          }),
        },
      ],
    }),
  },
};

const animate = (animatedValue: Animated.Value, toValue: number, callback?: () => void) => {
  Animated.spring(animatedValue, {
    toValue,
    damping: 10,
    mass: 0.35,
    stiffness: 100,
    overshootClamping: true,
    restSpeedThreshold: 0.001,
    restDisplacementThreshold: 0.001,
    useNativeDriver: true,
  }).start(() => callback?.());
};

const defaultOptions: ModalOptions = {
  backdropOpacity: 0.4,
  animationIn: animate,
  animationOut: animate,
  transitionOptions: (animatedValue) => ({
    opacity: animatedValue.interpolate({
      inputRange: [0, 1, 2],
      outputRange: [0, 1, 0.9],
    }),
    transform: [
      { perspective: 2000 },
      {
        translateX: animatedValue.interpolate({
          inputRange: [0, 1, 2],
          outputRange: [-width / 1.5, 0, width / 1.5],
          extrapolate: 'clamp',
        }),
      },
      {
        rotateY: animatedValue.interpolate({
          inputRange: [0, 1, 2],
          outputRange: ['90deg', '0deg', '-90deg'],
          extrapolate: 'clamp',
        }),
      },
      {
        scale: animatedValue.interpolate({
          inputRange: [0, 1, 2],
          outputRange: [1.2, 1, 0.9],
          extrapolate: 'clamp',
        }),
      },
    ],
  }),
  animateInConfig: {
    easing: Easing.bezier(0.42, -0.03, 0.27, 0.95),
    duration: 450,
  },
  animateOutConfig: {
    easing: Easing.bezier(0.42, -0.03, 0.27, 0.95),
    duration: 450,
  },
};

export const modalStack = createModalStack<ModalStackParamsList>(config, defaultOptions);
